function varargout = TLInterpolationnDDlg(action,varargin)

%TLINTERPOLATIONNDDLG Summary of this function goes here
%
%   TLINTERPOLATIONNDDLG(varagin) Detailed explanation goes here
%
%   Inputs:
%
%
%   Outputs:
%
%
%   Syntax:
%
%
%   Example:
%
%
%   See also:
%
% 
%   Author(s): Xiaobiao Huang
%   Copyright 2013-2020 The Xiaobiao Studio.
%   $Revision: 1.0.0.0 $  $Date: 08-Jul-2012 19:11:51 $

% TL_INTERPOLATION_N_D_DLG manages the user interface for TargetLink Interpolation (n-D) block
%
% SYNTAX dlgInfo = tl_interpolation_n_d_dlg('GetDlgInfo');
%   gets dialog info of TargetLink Interpolation (n-D) block
%
%   INPUT ARGUMENTS
%   -/-
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = tl_interpolation_n_d_dlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = tl_interpolation_n_d_dlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = tl_interpolation_n_d_dlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = tl_interpolation_n_d_dlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX tl_interpolation_n_d_dlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: tl_interpolation_n_d_dlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.17 $
% $Date: 2011/09/02 09:53:57MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'Interpolation Using Prelookup';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'General';
            'Output';
            'Table';
            'Logging & Autoscaling';
            'Documentation'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);
        
    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        excludedCtrls = {'saturate', 'inheritproperties', 'width', 'element', 'scalarExp'};
        switch pageName
            case 'General'
                [sheetDims, ctrlPos] = FcnCalcGeneralCtrlPositions(commonGeom);
                
            case 'Output'
                [sheetDims, ctrlPos] = tl_calc_ctrls_positions(commonGeom, excludedCtrls);
                
            case 'Table'
                [sheetDims, ctrlPos] = FcnCalcTableCtrlPositions(commonGeom);
                
            case 'Logging & Autoscaling'
                excludedCtrls = {'plotEdit'};
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
                
            case 'Documentation'
                % activate extra controls for table blocks
                bTblBlock = 1;
                bCodeComment = 1;
                [sheetDims, ctrlPos] = ...
                    TLManageDocCtrls('ctrlpos', commonGeom, sheetDims, ...
                    bCodeComment, bTblBlock);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;
        
    case 'Create'
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'General'
                dlgdata = FcnCreateGeneralCtrls(pageNum, dlgfig, dlgdata);
                
            case 'Output'
                dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
                dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);
                
            case 'Table'
                dlgdata = FcnCreateTableCtrls(pageNum, dlgfig, dlgdata);
                
            case 'Logging & Autoscaling'
                dlgdata =  TLManageLoggingCtrls('create', pageNum, dlgfig, dlgdata);
                
            case 'Documentation'
                dlgdata = FcnCreateDocumentationCtrls(pageNum, dlgfig, dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;
        
    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'General'
                [dlgdata, bModified] = FcnManageGeneralCtrls(pageNum, dlgdata, pageAction);
                
            case 'Output'
                [dlgdata, bModified1] = ...
                    TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'output');
                % output variable can be vectorized
                currentElement = dlgdata.extdata.output.currentElement;
                [dlgdata, bModified2] = ...
                    TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'output', currentElement);
                
                bModified = bModified1 || bModified2;
                
            case 'Table'
                [dlgdata, bModified] = FcnManageTableCtrls(pageNum, dlgfig, dlgdata, pageAction);
            case 'Logging & Autoscaling'
                [dlgdata, bModified] = ...
                    TLManageLoggingCtrls('manage', pageNum, dlgdata, pageAction, 'logdata');
            case 'Documentation'
                [dlgdata,bModified] = ...
                    FcnManageDocumentationCtrls(pageNum, dlgfig, dlgdata, pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified ;
        
    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'Update'
        dlgfig    = varargin{1};
        dlgdata   = varargin{2};
        pageNum   = varargin{3};
        
        pageName  = dlgdata.pageNames{pageNum};
        switch pageName
            case 'General'
                dlgdata = FcnUpdateGeneralCtrls(pageNum, dlgfig, dlgdata);
                
            case 'Output'
                dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'output');
                dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'output', []);
                
                TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
                TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
                
            case 'Table'
                dlgdata = FcnUpdateTableCtrls(pageNum, dlgfig, dlgdata);
                
            case 'Logging & Autoscaling'
                dlgdata =  TLManageLoggingCtrls('update',pageNum,dlgdata,'logdata','output');
                TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
                
            case 'Documentation'
                dlgdata = FcnUpdateDocumentationCtrls(pageNum, dlgfig, dlgdata);
        end
        varargout{1} = dlgdata;
        
    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;
        
    otherwise
        error(['Invalid action "' action '"']);
        
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end
        
    case 'ViewCode'
        switch dlgdata.pageNames{dlgdata.CurrentPageNum}
            case 'Table'
                blockVar = 'table';
                tl_create_links_to_model('ShowDeclaration',dlgdata.model, blockVar);
            otherwise
                blockVar = 'output';
                tl_create_links_to_model('ShowComputation',dlgdata.model, blockVar);
        end
        
    otherwise
        error('Invalid callback');
        
end % switch(action)


%-----------------------------------------------------------------------------------------
% FcnCalcGeneralCtrlPositions calculates positions for all controls on table page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcGeneralCtrlPositions(commonGeom)

% get sheet dimension of output tab
[sheetDims, outputCtrlPos, col, colDelta, rowDelta] = tl_calc_ctrls_positions(commonGeom, ...
    {'allscaling', 'scaling', 'type', 'class', 'var', 'element', 'width', 'address' 'name', 'unit', 'scalarExp', 'inheritproperties'});

strings_and_styles = {...
    'Data Dictionary look-up table object: ',   'text';...
    ' ',                                        'edit';...
    'n',                                        'pushbutton';...
    'Table:',                                   'text';...
    repmat('m',74),                             'edit';
    'Apply interpolation',                      'checkbox';...
    ['Distances between table entries ' ...
    'less than half of implemented range '],    'checkbox';...
    'Select:',                                  'text';...
    ' Scale Table ',                            'pushbutton';...
    'Number of table dimensions:',              'text';...
    '2     ',                                   'popupmenu'};
% blanks in string are necessary for correct view of popupmenu with large fonts

[ddLabelSize, ...
    ddEditSize, ...
    ddMenuButtonSize, ...
    tableLabelSize, ...
    tableEditSize, ...
    interCheckboxSize, ...
    boundCheckboxSize, ...
    selectLabelSize, ...
    autoscaleButtonSize, ...
    ndimsLabelSize, ...
    ndimsPopupSize] = ...
    ds_get_uicontrol_sizes(commonGeom,strings_and_styles);

% correct height, because on some platforms icon overlapped button boundary; icon height is 18 pixel.
ddMenuButtonSize(2) = max(22, ddMenuButtonSize(2));

% correct length of table edit field
tableEditSize(1) = outputCtrlPos.tlcgoptGroupbox(3) - 2*commonGeom.frameSideEdgeBuffer;
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + ...
    commonGeom.sheetBottomEdgeBuffer;

tableGroupboxWidth = outputCtrlPos.addoptGroupbox(3);
tableGroupboxHeight = 6 * commonGeom.editHeight ...
    + 2 * commonGeom.textHeight ...
    + 7 * rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;
ctrlPos.tableGroupbox = [cx, cy, tableGroupboxWidth, tableGroupboxHeight];

% positions for table controls
% autoscale button
cy = commonGeom.frameBottomEdgeBuffer;
cx = col(1);
ctrlPos.autoscaleButton = [cx cy interCheckboxSize];

% bounding points checkbox
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.boundCheckbox = [cx cy boundCheckboxSize];

% interpolation checkbox
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.interCheckbox = [cx cy interCheckboxSize];

% number of table dimensions label
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.ndimsLabel = [cx cy ndimsLabelSize];

% number of table dimensions popup
cx = cx + ndimsLabelSize(1) + colDelta / 3;
ctrlPos.ndimsPopup = [cx cy ndimsPopupSize];

% table Edit
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.tableEdit = [cx cy tableEditSize];
% table label
cy = cy + commonGeom.textHeight + rowDelta;
ctrlPos.tableLabel = [cx cy tableLabelSize];


% 2nd row
cy = cy + commonGeom.editHeight + rowDelta;

% DD field
cx = col(1);
dotButtonSize = [2*ddMenuButtonSize(1) ddMenuButtonSize(2)];
ddEditSize(1) = tableEditSize(1) - dotButtonSize(1);
ctrlPos.ddEdit = [cx cy ddEditSize];

% select button
cx = cx + ddEditSize(1);
ctrlPos.ddSelectButton = [cx,cy, dotButtonSize];
% DD menu button
cx = cx + ddMenuButtonSize(1);
ctrlPos.ddMenuButton = [cx+2,cy+2,ddMenuButtonSize(1)-4 ddMenuButtonSize(2)-4];


% 1st row
cy = cy + commonGeom.textHeight + rowDelta;
% DD label
cx = col(1);
ctrlPos.ddLabel = [cx cy ddLabelSize];

% increase sheet dimensions
sheetDims(2) = commonGeom.sheetTopEdgeBuffer ...
    + ctrlPos.tableGroupbox(4) ...
    + commonGeom.sheetBottomEdgeBuffer;


%-----------------------------------------------------------------------------------------
% FcnCreateGeneralCtrls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateGeneralCtrls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;
defColor = get(0, 'DefaultUIControlBackgroundColor');
userDataMenuButton.cDataEnabled  = tl_get_icon('ArrowHeadDown_10x18', 'BackgroundColor', defColor);
userDataMenuButton.cDataDisabled = tl_get_icon('ArrowHeadDown_10x18_disabled');
userDataSelectButton.cDataEnabled  = tl_get_icon('Browse_Seperator_24x18', 'BackgroundColor', defColor);
userDataSelectButton.cDataDisabled = tl_get_icon('Browse_Seperator_24x18');

% create the tableGroupbox which will contain table options
Children.tableGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',             {'Look-up options'}, ...
    'Units',             'pixels', ...
    'Position',          ctrlPos.tableGroupbox);

% dd controls
Children.ddLabel = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'text', ...
    'String',            'Data Dictionary look-up table object:', ...
    'Position',          ctrlPos.ddLabel);

Children.ddEdit = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'BackgroundColor',   'w', ...
    'Style',             'edit', ...
    'Position',          ctrlPos.ddEdit);

Children.ddSelectButton = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'pushbutton', ...
    'UserData',          userDataSelectButton, ...
    'CData',             userDataSelectButton.cDataEnabled, ...
    'Position',          ctrlPos.ddSelectButton);

Children.ddMenuButton = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'pushbutton', ...
    'UserData',          userDataMenuButton, ...
    'CData',             userDataMenuButton.cDataEnabled, ...
    'Position',          ctrlPos.ddMenuButton);

% define context menu for DataDictionary browse button
hdlgfig = get(dlgfig,'Parent');
ddCMenu = uicontextmenu('Parent', hdlgfig);
set(Children.ddEdit, 'UIContextMenu', ddCMenu);
set(Children.ddMenuButton, 'UIContextMenu', ddCMenu);
menu.select = uimenu(ddCMenu, ...
    'Label', 'Select', ...
    'Callback', sprintf('dstabdlg(''%s'',gcbf,''ddSelectButton'')', dlgdata.pageNames{pageNum}));
menu.show = uimenu(ddCMenu, ...
    'Label', 'Show in DD Manager', ...
    'Callback', sprintf('dstabdlg(''%s'',gcbf,''ddShowDDObject'')', dlgdata.pageNames{pageNum}), ...
    'Separator', 'on');
set(ddCMenu, 'UserData', menu);

% table controls
Children.tableLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Table:', ...
    'Position',           ctrlPos.tableLabel);

Children.tableEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.tableEdit);

Children.boundCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Distances between table entries less than half of implemented range', ...
    'Position',           ctrlPos.boundCheckbox);

Children.autoscaleButton = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             'Scale Table', ...
    'Position',           ctrlPos.autoscaleButton);

% number of dimensions
Children.ndimsLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Number of table dimensions:', ...
    'Position',           ctrlPos.ndimsLabel);

Children.ndimsPopup = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'popupmenu', ...
    'BackgroundColor',    'w', ...
    'String',             {'1','2'}, ...
    'Position',           ctrlPos.ndimsPopup);

Children.interCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Apply interpolation', ...
    'Position',           ctrlPos.interCheckbox);

dlgdata.pageData{pageNum}.children  = Children;


%-----------------------------------------------------------------------------------------
% FcnManageGeneralCtrls manage table controls
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageGeneralCtrls(pageNum, dlgdata, pageAction)

bModified = false;
Children = dlgdata.pageData{pageNum}.children;
panelPos = get(Children.tableGroupbox, 'Position');

switch pageAction
    
    case 'ddEdit'
        % Edit field: Get new module from edit field
        dlgdata.data.blockobject = tl_deblank(get(Children.ddEdit,'String'),2);
        bModified = true;
        
    case 'ddMenuButton',
        FcnSetMenuPosition(Children.ddMenuButton, panelPos(1:2));
        bModified = true;
        
    case 'ddSelectButton'
        dlgdata.data.blockobject = dsdd( 'SelectObject', ...
            'entryPath',       '/Pool/BlockSpecifications', ...
            'CurrentPath',     dlgdata.data.blockobject, ...
            'ObjectKind',      'Block');
        bModified = true;
        
    case 'ddShowDDObject'
        if dsdd('exist', ['/Pool/BlockSpecifications/' dlgdata.data.blockobject]);
            % jump to function object in DD Manager
            ddPath = ['/Pool/BlockSpecifications/' dlgdata.data.blockobject];
            dsddman('Select', ddPath);
        else
            % jump to node in DD Manager
            dsddman('Select', '/Pool');
        end
        
    case 'tableEdit'
        tStr = deblank(get(Children.tableEdit, 'String'));
        if ~isempty(tStr)
            if strcmp(tStr, 'ddv')
                if isempty(dlgdata.data.table.variable)
                    beep;
                else
                    dlgdata.data.table.value = ['ddv(''', dlgdata.data.table.variable, ''')'];
                    dlgdata.data.table.useddvariablevalue = true;
                end
            else
                dlgdata.data.table.value = tStr;
                % since value was changed without respect to a DD variable,
                % useddvariablevalue is assumed as 'off'
                dlgdata.data.table.useddvariablevalue = false;
            end
        else
            beep;
        end
        bModified = true;
        
    case 'ndimsPopup'
        dlgdata.data.ndims = get(Children.ndimsPopup, 'Value');
        bModified = true;
        
    case 'boundCheckbox'
        dlgdata.data.bounded = get(Children.boundCheckbox, 'Value');
        bModified = true;
        
    case 'interCheckbox'
        dlgdata.data.interpolate = get(Children.interCheckbox, 'Value');
        bModified = true;
        
    case 'autoscaleButton'
        ds_error_none;
        [dlgdata.data, bModified, msgstruct] = tl_scale_parameters( ...
            dlgdata.model, dlgdata.data);
        ds_error_register(msgstruct);
        ds_msgdlg('Update', ...
            'Title', ['Scaling of Interpolation (n-D) Block ' get_tlsubsystempath(dlgdata.model) ], ...
            'ShowErrors','yes', ...
            'ShowNotes','yes', ...
            'ShowWarnings','yes');
        
end


%-------------------------------------------------------------------------------
% FcnSetMenuPosition calculates position of contextmenu
%
% INPUT ARGUMENTS
%   ctrlHandle  handle of control
%   panelStart  cx position of panel
%
% OUTPUT ARGUMENTS
%   - / -
%-------------------------------------------------------------------------------
function FcnSetMenuPosition(ctrlHandle, panelStart)

pos = get(ctrlHandle, 'Position') + [panelStart 0 0];
cmenu = get(ctrlHandle, 'UIContextmenu');
commonGeom = ds_get_common_geometry;
textExtent = commonGeom.textExtent;
labelStrings = get(get(cmenu, 'Children'), 'Label');
maxext = 0;
for k = 1 : numel(labelStrings)
    set(textExtent, 'String', labelStrings{k});
    ext = get(textExtent, 'Extent');
    maxext = max(maxext, ext(3));
end
position = [pos(1)-32-maxext, pos(2)];
set(cmenu, 'Position', position, 'Visible', 'on');


%-----------------------------------------------------------------------------------------
% FcnUpdateGeneralCtrls updates General page
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateGeneralCtrls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
data = dlgdata.data;

bIsFullVs = dlgdata.bIsFullVs;
if bIsFullVs && dlgdata.bDSDDMan
    defaultStatusDD = 'on';
else
    defaultStatusDD = 'inactive';
end

[data, extdata] = tl_sync_dd_blockdata(data, 'BlockType', dlgdata.maskType);

ddEditCtrlStatus = struct('enable', defaultStatusDD);
ddEditCtrlStatus.string = data.blockobject;
ddEditCtrlStatus.iserror = 0;

ddSelectButtonCtrlStatus = struct('enable', defaultStatusDD); %#ok<NASGU>
ddMenuButtonCtrlStatus = struct('enable', defaultStatusDD); %#ok<NASGU>
% set status of context menu controls:
ddCMenu = get(Children.ddMenuButton, 'UIContextMenu');
ddMenu = get(ddCMenu, 'UserData');

menuSelectStatus = struct('enable', flag2str(bIsFullVs));
UserData = get(ddMenu.select, 'UserData');
UserData.ctrlStatus = menuSelectStatus;
set(ddMenu.select, 'UserData', UserData);

menuShowStatus = struct('enable', flag2str(dlgdata.bDSDDMan));
UserData = get(ddMenu.show, 'UserData');
UserData.ctrlStatus = menuShowStatus;
set(ddMenu.show, 'UserData', UserData);

% values and look-up method is independend of blockset mode
tableEditCtrlStatus = struct('enable', FcnbEnabled(extdata.table.bWritable.value, 1));
ndimsPopupCtrlStatus = struct('enable', FcnbEnabled(extdata.bWritable.ndims, 1), ...
    'string', {get(Children.ndimsPopup, 'String')});
interCheckboxCtrlStatus = struct('enable', FcnbEnabled(extdata.bWritable.interpolate, 1));

% get minima and maxima of table data
bReqMono = false;
bMatAllowed = data.ndims > 1;
[t, tmin, tmax, bCompliant] = tl_eval_table(data.table, bReqMono, bMatAllowed);
tableEditCtrlStatus.iserror = ~bCompliant;

tableEditCtrlStatus.string = data.table.value;
ndimsPopupCtrlStatus.value = data.ndims;
interCheckboxCtrlStatus.value = data.interpolate;

bTableInteger = ds_isa(['/Pool/Typedefs/' data.table.type], 'integertype');
bBoundEnable = extdata.bWritable.bounded && bTableInteger && data.interpolate;
boundCheckboxCtrlStatus = struct('enable', FcnbEnabled(bBoundEnable, bIsFullVs));
boundCheckboxCtrlStatus.value = data.bounded;

% initialize scale button status
autoscaleButtonCtrlStatus = struct('enable', 'on');
% activation of 'Scale Table' button
% special behaviour of table blocks: Scale button must be disabled if 'no autoscaling' is selected
bOutputInteger = ds_isa(['/Pool/Typedefs/' data.output.type], 'integertype');
bAutoscEnable = bOutputInteger ...
    && isempty(dsdd('GetConstraintsScalingRef', ['/Pool/Typedefs/' data.output.type])) ...
    && isempty(data.output.scaling);
bScaleButtonEnable = dlgdata.bIsFullVs && bAutoscEnable && data.autoscaling.mode == 1;
bIsGenericTable = isempty(data.blockobject);
autoscaleButtonCtrlStatus.enable = flag2str(bScaleButtonEnable && bIsGenericTable);

% set control status
ctrlsList = {
    'ddEdit' ...
    'ddSelectButton' ...
    'ddMenuButton' ...
    'autoscaleButton' ...
    'tableEdit' ...
    'ndimsPopup' ...
    'interCheckbox' ...
    'boundCheckbox'};

% write back control status of controls to the controls' UserData property
for ctrlsNo=1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of table parameter groupbox controls
TLSetCtrlsStatus(dlgfig, Children, ctrlsList);


%-----------------------------------------------------------------------------------------
% FcnCalcTableCtrlPositions calculates positions for all controls on Table page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcTableCtrlPositions(commonGeom)

excludedCtrls = {'saturate', 'inheritproperties', 'width', 'element', 'scalarExp'};
[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = { ...
    'Table:', 'text',
    'Use value of Data Dictionary variable', 'checkbox'};

[tableLabelSize, useDDValueCheckboxSize] = ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% control positions of controls of table options group box
% define new height for addoptGroupbox
ctrlPos.addoptGroupbox(4) = commonGeom.editHeight ...
    + commonGeom.checkboxHeight ...
    + rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;

%---------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% ddv checkbox
cx = col(2);
ctrlPos.useDDValueCheckbox = [cx, cy, useDDValueCheckboxSize];

%---------------------------------------
% 1st row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% table options label
cx = col(1);
ctrlPos.tableLabel  = [cx cy tableLabelSize];

% table options edit field
cx = ctrlPos.descEdit(1);
ctrlPos.tableEdit  = [cx cy ctrlPos.descEdit(3:4)];

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.textHeight;


%-----------------------------------------------------------------------------------------
% FcnCreateTableCtrls creates Table controls page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateTableCtrls(pageNum, dlgfig, dlgdata)

% invoke standard function to create scaling controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;

% create the addoptGroupbox which will contain table values
Children.addoptGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Table values'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.addoptGroupbox);

% table controls
Children.tableLabel = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'text', ...
    'String',             'Table:', ...
    'Position',           ctrlPos.tableLabel);

Children.tableEdit = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.tableEdit);

Children.useDDValueCheckbox = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use value of Data Dictionary variable', ...
    'Position',           ctrlPos.useDDValueCheckbox);

dlgdata.pageData{pageNum}.children = Children;

%-----------------------------------------------------------------------------------------
% FcnManageTableCtrls manages Table page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageTableCtrls(pageNum, dlgfig, dlgdata, pageAction)

Children = dlgdata.pageData{pageNum}.children;

switch pageAction
    
    case 'tableEdit'
        tStr = deblank(get(Children.tableEdit, 'String'));
        if ~isempty(tStr)
            if strcmp(tStr, 'ddv')
                if isempty(dlgdata.data.table.variable)
                    beep;
                else
                    dlgdata.data.table.value = ['ddv(''', dlgdata.data.table.variable, ''')'];
                    dlgdata.data.table.useddvariablevalue = true;
                end
            else
                dlgdata.data.table.value = tStr;
            end
        else
            beep;
        end
        bModified = true;
        
    case 'useDDValueCheckbox'
        if get(Children.useDDValueCheckbox, 'Value')
            dlgdata.data.table.value = ['ddv(''', dlgdata.data.table.variable, ''')'];
            dlgdata.data.table.useddvariablevalue = true;
        else
            dlgdata.data.table.useddvariablevalue = false;
        end
        bModified = true;
        
    otherwise
        [dlgdata, bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'table');
        [dlgdata, bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'table');
        
        bModified = bModified1 | bModified2;
        
end


%--------------------------------------------------------------------------
% FcnUpdateTableCtrls updates the controls of the Table tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateTableCtrls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
tableEditCtrlStatus = struct('enable', 'on', 'string', '');
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'table');

% get minima and maxima of table data
bReqMono = false;
bMatAllowed = dlgdata.data.ndims > 1;
[t, tmin, tmax, bCompliant] = tl_eval_table(dlgdata.data.table, bReqMono, bMatAllowed);
if bCompliant
    constraint = [tmin tmax];
else
    constraint = [];
end

dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'table', constraint);

% table value cannot be edited if a look-up table object specifies all
% block data
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~dlgdata.data.table.useddvariablevalue;
tableEditCtrlStatus.string = dlgdata.data.table.value;
tableEditCtrlStatus.enable = FcnbEnabled(bWritable, 1);
tableEditCtrlStatus.iserror = ~bCompliant;

% status of ddv checkbox
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~isempty(dlgdata.data.table.variable);
useDDValueCheckboxCtrlStatus.enable = flag2str(bWritable);
useDDValueCheckboxCtrlStatus.value = dlgdata.data.table.useddvariablevalue;

% read ranges' CtrlStatus
simulatedLabelCtrlStatus = tl_get_control_userdata(Children.simulatedLabel);
upperSimulatedValueCtrlStatus = tl_get_control_userdata(Children.upperSimulatedValue);
lowerSimulatedValueCtrlStatus = tl_get_control_userdata(Children.lowerSimulatedValue);

if ~isempty(t) && bCompliant
    minstr = sprintf('%0.5g', tmin);
    maxstr = sprintf('%0.5g', tmax);
else
    minstr = 'n.a.';
    maxstr = 'n.a.';
end

if dlgdata.data.ndims == 1
    simulatedLabelCtrlStatus.string = 'of vector';
else
    simulatedLabelCtrlStatus.string = 'of matrix';
end
upperSimulatedValueCtrlStatus.string = maxstr;
lowerSimulatedValueCtrlStatus.string = minstr;

% set control status
ctrlsList = {
    'tableEdit' ...
    'simulatedLabel' ...
    'upperSimulatedValue' ...
    'lowerSimulatedValue' ...
    'useDDValueCheckbox'
    };
for ctrlsNo = 1:numel(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of variable, scaling and table parameter groupbox controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLSetCtrlsStatus(dlgfig, Children, {'tableEdit', 'useDDValueCheckbox'});


%-----------------------------------------------------------------------------------------
% FcnCreateDocumentationCtrls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateDocumentationCtrls(pageNum, dlgfig, dlgdata)

% invoke generic function to create documentation page
dlgdata = TLManageDocCtrls('create',pageNum,dlgfig,dlgdata);

% create additional controls
Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
Children.tblFcnName   = uicontrol( ...
    'Parent',            dlgfig, ...
    'Style',             'text', ...
    'String',            'Table function name: n.a.', ...
    'Position',          ctrlPos.tblFcnName);
Children.clipboardButton = uicontrol( ...
    'Parent',            dlgfig, ...
    'Style',             'pushbutton', ...
    'String',            'Copy to Clipboard', ...
    'Position',          ctrlPos.clipboardButton);

% save extended children handle structure
dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageDocumentationCtrls manage control actions of ducumentation page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata,bModified] = FcnManageDocumentationCtrls(pageNum, dlgfig, dlgdata, pageAction)

% default return value
bModified = 0;

% clipboard callbacks are handled directly here
if strcmp(pageAction, 'clipboardButton')
    clipboard('copy', dlgdata.pageData{pageNum}.tblFcnName);
    return
end

% invoke generic function to manage control callbacks
[dlgdata, bModified] = TLManageDocCtrls('callback', pageNum, dlgfig, ...
    dlgdata,pageAction);


%-----------------------------------------------------------------------------------------
% FcnUpdateDocumentationCtrls updates documentation page
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateDocumentationCtrls(pageNum, dlgfig, dlgdata)

TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;
bReqMono = false;
bMatAllowed = dlgdata.data.ndims > 1;
t = tl_eval_table(dlgdata.data.table, bReqMono, bMatAllowed);
tblFcnName = 'n.a.';
if ~isempty(t)
    % invoke get_plktabledata in batch mode
    b = ds_error_get('batchmode');
    ds_error_set('batchmode','on');
    [tableData,msgstruct] = get_plktabledata(dlgdata.data,t,inf);
    ds_error_set('batchmode',b);
    
    % determine tablefunction name
    if isempty(msgstruct) || ~any(strcmp({msgstruct.type},'Error'))
        tblFcnName = tl_get_tblfcnnames(dlgdata.data,dlgdata.model,tableData,dlgdata.maskType);
    end
    if iscell(tblFcnName)
        tblFcnName = [tblFcnName{:}];
    end
end

tblFcnNameCtrlStatus = struct('enable', 'on');
clipboardButtonCtrlStatus = struct('enable', 'on');
tblFcnNameCtrlStatus.string = sprintf('Table function name: %s', tblFcnName);
clipboardButtonCtrlStatus.enable = flag2str(~isempty(tblFcnName) && ~strcmp(tblFcnName, 'n.a.'));
ctrlsList = {'tblFcnName', 'clipboardButton'};
for ctrlsNo=1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end
TLSetCtrlsStatus(dlgfig, Children, ctrlsList);

% save table function name at dialog data structure
dlgdata.pageData{pageNum}.tblFcnName = tblFcnName;

%-----------------------------------------------------------------------------------------
% FcnbEnabled to get status for control
%
% INPUT ARGUMENTS
%   bWritable       is control write able
%   defaultStatus   is full version
%
% OUTPUT ARGUMENTS
%   enableStatus    status is 'on' or 'inactive'
%-----------------------------------------------------------------------------------------
function enableStatus = FcnbEnabled(bWritable, defaultStatus)

if defaultStatus && bWritable
    enableStatus = 'on';
else
    enableStatus = 'inactive';
end


% end % end of function  TLInterpolationnDDlg
